package com.atguigu.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;

public class Ftp {
	private final static String destType = "";
	private final static String basePath = "";
	private final static String readMode = "";
	private final static String ftpAddress = "";
	private final static int ftpPort = -1;
	private final static String ftpUsername = "";
	private final static String ftpPassword = "";
	
	
	public static FTPClient getFTPClient(String ftpHost, int ftpPort,String controlEncoding, String ftpUserName, String ftpPassword){  
        FTPClient ftpClient =  new FTPClient(); 
        try {  
        	ftpClient.setControlEncoding(controlEncoding);//设置编码
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器  
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器  
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);//设置传输的文件类型 
            //ftpClient.enterLocalPassiveMode();//ftpClient.enterRemotePassiveMode();
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {          
                ftpClient.abort();
                ftpClient.disconnect();  //断开服务
            }
        } catch (SocketException e) {  
            e.printStackTrace();           
        } catch (IOException e) {  
            e.printStackTrace();             
        }  
        return ftpClient;  
    }  
	
	public static boolean closeFTPConnect(FTPClient ftpClient) {
    	boolean flag = false;
		try {
			if (ftpClient != null && ftpClient.isConnected()) {
				//ftpClient.abort();
				ftpClient.disconnect();
				flag=true;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	public static boolean uploadFtpFile(FTPClient ftpClient,String ftpFile ,String localFile){ 
    	boolean  flag=false;
        if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return false;
        if(ftpFile==null || "".equals(ftpFile) ) return false;
        if(localFile==null || "".equals(localFile) ) return false;
        String  ftpFilePath = ftpFile.substring(0,ftpFile.lastIndexOf("/"));
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
        String	localSuffix = localFile.substring(localFile.lastIndexOf(".")+1);
        if(ftpFile.equals(ftpSuffix)) return false;
        if(localFile.equals(localSuffix)) return false;
        FileInputStream fis = null; 
        try { 
            if (!(new File(localFile)).exists())   return false;//文件是否存在
            fis = new FileInputStream(localFile); 
            
            ftpClient.changeWorkingDirectory("/"); 
            String[] dirs = ftpFilePath.split("/");
            for (String workDir : dirs) {
				if (!StringUtils.isBlank(workDir)) {
					ftpClient.makeDirectory(workDir);
					ftpClient.changeWorkingDirectory(workDir);
				}
			}
            if(ftpSuffix.equals(localSuffix)) { // 不是office文件，直接存储源文件
            	flag = ftpClient.storeFile(ftpFile, fis);  
            }else { // 是office，不仅需要存储源文件，还要转换成pdf存储
            	 if("doc,docx".contains(localSuffix)) {
            		 flag = AsposeOfficeUtil.word(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                 }else if("xls,xlsx".contains(localSuffix)) {
                	 flag = AsposeOfficeUtil.excel(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                 }if("ppt,pptx".contains(localSuffix)) {
                	 flag = AsposeOfficeUtil.ppt(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                 }
            }
            flag=true;
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            try { 
            	if(fis!=null) fis.close();
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
        return flag;
    }

	public static boolean uploadFtpFile(FTPClient ftpClient,String ftpFile,InputStream fis,String localSuffix ){ 
        boolean  flag=false;
        if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return false;
        if(ftpFile==null || "".equals(ftpFile) ) return false;
        if(localSuffix==null || "".equals(localSuffix) ) return false;
        String  ftpFilePath = ftpFile.substring(0,ftpFile.lastIndexOf("/"));
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
        if(ftpFile.equals(ftpSuffix)) return false;
        if (fis==null)   return false;//文件是否存在
        try { 
        	ftpClient.changeWorkingDirectory("/"); 
        	 String[] dirs = ftpFilePath.split("/");
             for (String workDir : dirs) {
 				if (!StringUtils.isBlank(workDir)) {
 					ftpClient.makeDirectory(workDir);
 					ftpClient.changeWorkingDirectory(workDir);
 				}
 			}
            if(ftpSuffix.equals(localSuffix)) { // 不是office文件，直接存储源文件
            	flag = ftpClient.storeFile(ftpFile, fis);  
            }else { // 是office，不仅需要存储源文件，还要转换成pdf存储
             	 if("doc,docx".contains(localSuffix)) {
             		flag = AsposeOfficeUtil.word(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                  }else if("xls,xlsx".contains(localSuffix)) {
                	  flag = AsposeOfficeUtil.excel(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                  }if("ppt,pptx".contains(localSuffix)) {
                	  flag = AsposeOfficeUtil.ppt(fis, ftpClient.appendFileStream(ftpFile),"pdf");
                  }
            }           
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            try { 
            	if(fis!=null) fis.close();
            } catch (IOException e) { 
                e.printStackTrace();              
            } 
        } 
        return flag;
    }

	public static boolean uploadFtpFile(FTPClient ftpClient,String ftpFile,byte[] bytes,String localSuffix ){ 
        boolean  flag=false;
        if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return false;
        
        if(ftpFile==null || "".equals(ftpFile) ) return false;
        if(localSuffix==null || "".equals(localSuffix) ) return false;
        String  ftpFilePath = ftpFile.substring(0,ftpFile.lastIndexOf("/"));
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
        if(ftpFile.equals(ftpSuffix)) return false;
        if (bytes==null)   return false;//文件是否存在
        try { 
        	ftpClient.changeWorkingDirectory("/"); 
        	 String[] dirs = ftpFilePath.split("/");
             for (String workDir : dirs) {
 				if (!StringUtils.isBlank(workDir)) {
 					ftpClient.makeDirectory(workDir);
 					ftpClient.changeWorkingDirectory(workDir);
 				}
 			}
             
            if(ftpSuffix.equals(localSuffix)) { // 不是office文件，直接存储源文件
            	flag = ftpClient.storeFile(ftpFile, new ByteArrayInputStream(bytes));  
            }else { // 是office，不仅需要存储源文件，还要转换成pdf存储
              	 if("doc,docx".contains(localSuffix)) {
       
              		flag = AsposeOfficeUtil.word(new ByteArrayInputStream(bytes), ftpClient.appendFileStream(ftpFile),"pdf");
                   }else if("xls,xlsx".contains(localSuffix)) {
                	   flag = AsposeOfficeUtil.excel(new ByteArrayInputStream(bytes), ftpClient.appendFileStream(ftpFile),"pdf");
                   }if("ppt,pptx".contains(localSuffix)) {
                	   flag = AsposeOfficeUtil.ppt(new ByteArrayInputStream(bytes), ftpClient.appendFileStream(ftpFile),"pdf");
                   }
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        return flag;
    }

	public static boolean downloadFtpFile(FTPClient ftpClient, String ftpFile, String localFile){  
    	boolean flag = false;
        if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return false;
        if(ftpFile==null || "".equals(ftpFile) ) return false;
        if(localFile==null || "".equals(localFile) ) return false;
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
        String	localSuffix = localFile.substring(localFile.lastIndexOf(".")+1);
        if(ftpFile.equals(ftpSuffix)) return false;
        if(localFile.equals(localSuffix)) return false;
        OutputStream os=null;
        try {  
        	ftpClient.changeWorkingDirectory("/"); 
        	flag = ftpClient.retrieveFile(ftpFile, new FileOutputStream(localFile)); 
        } catch (FileNotFoundException e) {            
            e.printStackTrace();             
        } catch (SocketException e) {             
            e.printStackTrace();            
        } catch (IOException e) {  
            e.printStackTrace();  
        }finally { 
            try {  if(os!=null)  os.close(); } catch (IOException e) {  e.printStackTrace();  } 
        }   
        return flag;
    }
	
	public static byte[] downloadFtpFile(FTPClient ftpClient, String ftpFile){  
    	byte[] bytes =null;
        if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return null;
        if(ftpFile==null || "".equals(ftpFile) ) return null;
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
        if(ftpFile.equals(ftpSuffix)) return null;
        InputStream is =null;
    	ByteArrayOutputStream bos=null; 
        try {  
        	ftpClient.changeWorkingDirectory("/"); 
        	is = ftpClient.retrieveFileStream(ftpFile); 
        	if(is == null || ftpClient.getReplyCode() == FTPReply.FILE_UNAVAILABLE){
                return null;
            }else {
            	bos =new ByteArrayOutputStream();
            	byte[] b= new byte[1024];
            	int i=0;
            	while((i= is.read(b, 0, b.length))>0) {
            		bos.write(b, 0, i);
            	}
            	bytes = bos.toByteArray();
            	if(is!=null) is.close();
        		if(bos!=null) bos.close();
	        	ftpClient.completePendingCommand();
            }    
        } catch (FileNotFoundException e) {  
            e.printStackTrace();   
        } catch (SocketException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();   
        }
       return bytes;
    }

	public static Boolean deleteFtpFile(FTPClient ftpClient, String ftpFile) {
    	boolean flag = false;
    	if (!ftpClient.isConnected() || !ftpClient.isAvailable())  return  false;
    	String  ftpFilePath = ftpFile.substring(0,ftpFile.lastIndexOf("/"));
        String 	ftpSuffix = ftpFile.substring(ftpFile.lastIndexOf(".")+1);
    	try {
    		if(!ftpFile.equals(ftpSuffix)) { 
    			flag = ftpClient.deleteFile(ftpFile);
    			if ( ftpClient.changeWorkingDirectory(ftpFilePath) ) {
    				FTPFile[] ftpFiles = ftpClient.listFiles();
    				if(ftpFiles.length<=0) {
    					String workingDirectory = ftpClient.printWorkingDirectory();//当前目录名
    					ftpClient.changeToParentDirectory();
    					flag = ftpClient.removeDirectory(workingDirectory);
    				}
    			}
    		}
		} catch (IOException e) {
			e.printStackTrace();
		}
    	return flag;
    }
	
	public static boolean fileUpload(byte[] bytes,String suffix,String majorName,String optionName,String fileCode) {
		boolean flat = false;
		try {
			// 文件上传
			if ("LOCAL".equals(destType)) {// a.本地上传
				flat = fileUpload2local(bytes,suffix,majorName,optionName,fileCode);	
			} else if ("FTP".equals(destType)) {// b.FTP上传
				FTPClient ftpClient = getFTPClient(ftpAddress, ftpPort, "gbk",ftpUsername, ftpPassword);
				flat = fileUpload2ftp(ftpClient,bytes, suffix, majorName, optionName,fileCode);
				closeFTPConnect(ftpClient);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flat;
	}
	
	private static boolean fileUpload2ftp(FTPClient ftpClient,byte[] bytes, String suffix, String majorName, String optionName,
			String fileCode) {
		boolean flag = false;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		flag = uploadFtpFile(ftpClient,sourcePath+"/"+fileCode+"."+suffix,bytes,suffix );
		if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
			flag = uploadFtpFile(ftpClient,pdfPath+"/"+fileCode+".pdf",bytes,suffix );
		}
		return flag;
	}
	
	private static boolean fileUpload2local(byte[] bytes, String suffix, String majorName, String optionName,
			String fileCode) {
		boolean flag = false;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		if (!(new File(sourcePath)).exists())  new File(sourcePath).mkdirs();	
		if (!(new File(pdfPath)).exists())  new File(pdfPath).mkdirs();	
		try {
			storeFile(bytes,new FileOutputStream(sourcePath+"/"+fileCode+"."+suffix));
			flag = true;
			if("doc,docx".contains(suffix)) {
				flag = AsposeOfficeUtil.word(new ByteArrayInputStream(bytes),new FileOutputStream(pdfPath+"/"+fileCode+".pdf"),"pdf");
			}else if("xls,xlsx".contains(suffix)) {
				flag = AsposeOfficeUtil.excel(new ByteArrayInputStream(bytes),new FileOutputStream(pdfPath+"/"+fileCode+".pdf"),"pdf");
			}if("ppt,pptx".contains(suffix)) {
				flag = AsposeOfficeUtil.ppt(new ByteArrayInputStream(bytes),new FileOutputStream(pdfPath+"/"+fileCode+".pdf"),"pdf");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	public static boolean fileDelete( String suffix,String majorName, String optionName, String fileCode ){
    	boolean flat=false;
    	try {
			// 文件上传
			if ("LOCAL".equals(destType)) {// a.本地上传
				flat = fileDelete2local(suffix,majorName,optionName,fileCode);	
			} else if ("FTP".equals(destType)) {// b.FTP上传
				FTPClient ftpClient = getFTPClient(ftpAddress, ftpPort, "gbk",ftpUsername, ftpPassword);
				flat = fileDelete2ftp(ftpClient,suffix,majorName,optionName,fileCode);
				closeFTPConnect(ftpClient);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flat;
	}
	
	private static boolean fileDelete2ftp(FTPClient ftpClient,String suffix, String majorName, String optionName, String fileCode) {
		boolean flag = false;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		flag = deleteFtpFile(ftpClient, sourcePath+"/"+fileCode+"."+suffix);
		if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
			flag = deleteFtpFile(ftpClient,pdfPath+"/"+fileCode+".pdf");
		}
		return flag;
	}

	private static boolean fileDelete2local(String suffix, String majorName, String optionName, String fileCode) {
		boolean flag = false;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		File sourceFile =  new File(sourcePath+"/"+fileCode+"."+suffix);
		File pdfFile =  new File(pdfPath+"/"+fileCode+".pdf");
		flag = sourceFile.delete();
		if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
			flag = pdfFile.delete();
		}
		return flag;
	}

	public static byte[] filePreview(String suffix, String majorName, String optionName, String fileCode ) {
		byte[] bytes=null;
		try {
			// 文件上传
			if ("LOCAL".equals(destType)) {// a.本地上传
				bytes = filePreview2local(suffix,majorName,optionName,fileCode);	
			} else if ("FTP".equals(destType)) {// b.FTP上传
				FTPClient ftpClient = getFTPClient(ftpAddress, ftpPort, "gbk",ftpUsername, ftpPassword);
				if("tmp".equals(readMode)) { //缓存文件
					bytes = filePreview2tmp(ftpClient,suffix,majorName,optionName,fileCode);
				}else if("binary".equals(readMode)) {//二进制
					bytes = filePreview2binary(ftpClient,suffix,majorName,optionName,fileCode);
				}else if("diskmap".equals(readMode)) {//磁盘映射
					bytes = filePreview2diskmap(ftpClient,suffix,majorName,optionName,fileCode);
				}
				closeFTPConnect(ftpClient);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return bytes;
	}
	
	private static byte[] filePreview2diskmap(FTPClient ftpClient,String suffix, String majorName, String optionName, String fileCode) {
		byte[] bytes =null;
		String sourceUrl = "files/"+majorName+"-"+optionName+"/"+"src";
		String pdfUrl = "files/"+majorName+"-"+optionName+"/"+"pdf";
		try {
			if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
				bytes = (pdfUrl+"/"+fileCode+".pdf").getBytes("utf-8");
			}else {
				bytes = (sourceUrl+"/"+fileCode+"."+suffix).getBytes("utf-8");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	private static byte[] filePreview2binary(FTPClient ftpClient,String suffix, String majorName, String optionName, String fileCode) {
		byte[] bytes =null;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		if ("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
			bytes = downloadFtpFile(ftpClient, pdfPath+"/"+fileCode+".pdf" );
		}else {
			bytes = downloadFtpFile(ftpClient, sourcePath+"/"+fileCode+"."+suffix );
		}
		return bytes;
	}

	private static byte[] filePreview2tmp(FTPClient ftpClient,String suffix, String majorName, String optionName, String fileCode) {
		byte[] bytes =null;
		String sourcePath = basePath+"/"+majorName+"-"+optionName+"/"+"src";
		String pdfPath = basePath+"/"+majorName+"-"+optionName+"/"+"pdf";
		
		String tmp = Ftp.class.getResource("/").getPath().substring(1);
		tmp = tmp.substring(0,tmp.indexOf("/"));
		String tmpPath = tmp+"/"+"files"+"/"+"tmp";
		System.out.println(tmpPath);
		if(!(new File(tmpPath).exists())) new File(tmpPath).mkdirs();
		try {
			if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
				if( new File(tmpPath+"/"+fileCode+".pdf").exists() ) {
					bytes =("files/tmp/"+fileCode+".pdf").getBytes("utf-8");
				}else {
					if( downloadFtpFile(ftpClient, pdfPath+"/"+fileCode+".pdf", 
							tmpPath+"/"+fileCode+".pdf")) {
						bytes =("files/tmp/"+fileCode+".pdf").getBytes("utf-8");
					}
				}
				
			}else {
				if( new File(tmpPath+"/"+fileCode+"."+suffix).exists() ) {
					bytes =("files/tmp/"+fileCode+"."+suffix).getBytes("utf-8");
				}else {
					if( downloadFtpFile(ftpClient, sourcePath+"/"+fileCode+"."+suffix, 
							tmpPath+"/"+fileCode+"."+suffix)) {
						bytes =("files/tmp/"+fileCode+"."+suffix).getBytes("utf-8");
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	private static byte[] filePreview2local(String suffix, String majorName, String optionName, String fileCode) {
		byte[] bytes =null;
		String sourceUrl = "files/"+majorName+"-"+optionName+"/src";
		String pdfUrl =  "files/"+majorName+"-"+optionName+"/pdf";
		try {
			if("doc,docx,xls,xlsx,ppt,pptx".contains(suffix)) {
				bytes = (pdfUrl+"/"+fileCode+".pdf").getBytes("utf-8");
			}else {
				bytes = (sourceUrl+"/"+fileCode+"."+suffix).getBytes("utf-8");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	public static void main(String[] args) throws IOException {
		boolean flag = false; 
		String file ="G:\\ftp\\14.docx";
		String suffix ="png";
		String majorName ="协议规范";
		String optionName ="技术规范";
		String fileCode ="105C32D7DD10436ABD10A676A5AEA1421584952877";
		byte[] bytes = file2byte(file);
		
		//flag = fileUpload(bytes, suffix, majorName, optionName, fileCode);
		//flag = fileDelete(suffix,majorName,optionName,fileCode );
		//System.out.println(flag);
		byte[] b = filePreview(suffix,  majorName, optionName,fileCode );
		System.out.println(new String(b,"utf-8"));
		
		//System.out.println(new File("G:\\df\\dd\\tsd.txt").exists());
	}

	public static boolean storeFile(InputStream is, OutputStream os) {
		boolean flag = false;
    	if(is == null || os == null) return false;
    	int bytesRead = 0;
		byte[] buffer = new byte[8192];
		try {
			while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
			flag = true;
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try { is.close(); os.close(); } catch (IOException e) { e.printStackTrace(); }			
		}
		return flag;
	}

	public static void storeFile(byte[] bytes, FileOutputStream fileOutputStream) throws IOException {
    	FileChannel  fileChannel= fileOutputStream.getChannel();
    	MappedByteBuffer mbb= fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, bytes.length);
    	mbb.put(bytes, 0, bytes.length);
    	fileChannel.close();
   	}

	private static byte[] file2byte(String file) throws IOException {
		byte[] bytes= null;
		InputStream is = new FileInputStream(file);
		ByteArrayOutputStream bos =new ByteArrayOutputStream();
    	byte[] b= new byte[1024];
    	int i=0;
    	while((i= is.read(b, 0, b.length))>0) {
    		bos.write(b, 0, i);
    	}
    	bytes = bos.toByteArray();
		if(is!=null)is.close();
		if(bos!=null)bos.close();
		return bytes;
	}
}
